#include "pch.hpp"
#include "Object.hpp"
#include "System.hpp"
#include "ScriptComponent.hpp"




Engine::Entity::Object::Object(System* system)
	: m_system(system)
	, m_numComponents(0)
{
	assert(system != nullptr);
}
///////////////////////////////////////////////////////////////////////////////////////////////////

Engine::Entity::Object::~Object()
{
	m_system->detach_all(this);
}
///////////////////////////////////////////////////////////////////////////////////////////////////




unsigned int Engine::Entity::Object::numComponents() const
{
	return m_numComponents;
}
///////////////////////////////////////////////////////////////////////////////////////////////////




void Engine::Entity::Object::attach(Component* arg)
{
	auto component = Script::pointer<Component>(arg);

	if(m_system->attach(this, component))
		++m_numComponents;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Engine::Entity::Object::detach(Component* arg)
{
	auto component = Script::pointer<Component>(arg);

	if(m_system->detach(this, component))
		--m_numComponents;
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Engine::Entity::Object::attach(asIScriptObject* arg)
{
	auto object = Script::pointer<asIScriptObject>(arg);
	attach(new ScriptComponent(m_system->scriptSystem()->contextPool(), object));
}
///////////////////////////////////////////////////////////////////////////////////////////////////

void Engine::Entity::Object::detach(asIScriptObject* arg)
{
	auto object = Script::pointer<asIScriptObject>(arg);
	detach(new ScriptComponent(m_system->scriptSystem()->contextPool(), object));
}
///////////////////////////////////////////////////////////////////////////////////////////////////




void Engine::Entity::Object::registerType(Script::System::ptr engine)
{
	engine->registerObjectType("Entity", 0, asOBJ_REF);
	//engine->registerObjectBehaviour("Entity", asBEHAVE_FACTORY, "Entity@ f()", asFUNCTION(Entity::create), asCALL_CDECL);
	engine->registerObjectBehaviour("Entity", asBEHAVE_ADDREF, "void f()", asMETHOD(Script::Object, AddRef), asCALL_THISCALL);
	engine->registerObjectBehaviour("Entity", asBEHAVE_RELEASE, "void f()", asMETHOD(Script::Object, Release), asCALL_THISCALL);

	engine->registerObjectMethod("Entity", "void attach(Component@)", asMETHODPR(Object, attach, (Component*), void), asCALL_THISCALL);
	engine->registerObjectMethod("Entity", "void detach(Component@)", asMETHODPR(Object, detach, (Component*), void), asCALL_THISCALL);
	engine->registerObjectMethod("Entity", "void attach(ScriptComponent@)", asMETHODPR(Object, attach, (asIScriptObject*), void), asCALL_THISCALL);
	engine->registerObjectMethod("Entity", "void detach(ScriptComponent@)", asMETHODPR(Object, detach, (asIScriptObject*), void), asCALL_THISCALL);
	engine->registerObjectMethod("Entity", "uint32 numComponents()", asMETHOD(Object, numComponents), asCALL_THISCALL);
}
///////////////////////////////////////////////////////////////////////////////////////////////////
